package cn.crystalorigin.plugin.event

import cn.crystalorigin.plugin.AsyncLoader
import cn.crystalorigin.plugin.Core
import cn.crystalorigin.plugin.util.thread.ioScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.bukkit.Bukkit
import java.util.concurrent.CopyOnWriteArrayList

object TickEventRunner : AsyncLoader() {
    override val name = "TickManager"
    private val consumers = CopyOnWriteArrayList<() -> Unit>()
    private val suspendingConsumers = CopyOnWriteArrayList<suspend () -> Unit>()

    override suspend fun load() {
        Bukkit.getScheduler().runTaskTimer(Core.INSTANCE, {

        }, 0, 1)
    }

    fun runTask() {
        runBlocking {
            suspendingConsumers.forEach {
                ioScope.launch { it() }
            }
            consumers.forEach { it() }
        }
    }

    fun onTick(func: () -> Unit) = func.also { consumers.add(it) }

    fun onTick(func: Runnable) = this.onTick { func.run() }

    fun onTickSuspend(func: suspend () -> Unit): suspend () -> Unit = func.also { suspendingConsumers.add(it) }

    fun onTickSuspend(func: Runnable): suspend () -> Unit = this.onTickSuspend { func.run() }

    fun (() -> Unit).cancel() = consumers.remove(this)
}